package cn.tedu.mall.search.service.impl;

import cn.tedu.mall.common.restful.JsonPage;
import cn.tedu.mall.pojo.product.model.Spu;
import cn.tedu.mall.pojo.search.entity.SpuForElastic;
import cn.tedu.mall.product.service.front.IForFrontSpuService;
import cn.tedu.mall.search.repository.SpuForElasticRepository;
import cn.tedu.mall.search.service.ISearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SearchServiceImpl implements ISearchService {

    // dubbo调用product模块分页查询所有spu信息的方法
    @DubboReference
    private IForFrontSpuService dubboSpuService;
    @Autowired
    private SpuForElasticRepository spuRepository;

    // ES加载spu信息的方法
    @Override
    public void loadSpuByPage() {
        // 基本思路是从数据库查询出当前页spu信息,在批量增到ES中
        // 但是在运行第一个查询之前,我们并不知道总页数,也就无法确定循环次数
        // 只有运行了第一次查询,才能从JsonPage中获取总页数信息,来确定循环次数
        // 所以匹配"先运行,后判断"的情况,使用do-while循环结构更合适
        int i=1;    // 循环变量,定义i从1开始,直接当做页码使用
        int pages;  // 总页数的声明也是循环次数,声明时不需要赋值,循环中赋值即可
        do {
            // 循环首先的操作就是Dubbo查询spu表中的一页信息
            // 实际开发中pageSize一般都是500以上,这里写2只是为了测试时有分页效果
            JsonPage<Spu> spus=dubboSpuService.getSpuByPage(i,2);
            // 上面查询结果泛型类型是Spu,Spu是不能向ES中执行新增的
            // 所以要先转换为能执行ES新在的类型:List<SpuForElastic>
            List<SpuForElastic> list=new ArrayList<>();
            for(Spu spu : spus.getList()){
                // 循环中对spu进行转换,目标为SpuForElastic
                SpuForElastic esSpu=new SpuForElastic();
                BeanUtils.copyProperties(spu, esSpu);
                // 将转换完成的对象esSpu新增到list集合中
                list.add(esSpu);
            }
            // 转换完成,将List<SpuForElastic>集合批量新增到ES
            spuRepository.saveAll(list);
            log.info("成功加载第{}页信息",i);
            i++; // 循环遍历自增
            // 为pages总页数赋值
            pages=spus.getTotalPage();
        }while (i<=pages);

    }

    // 根据用户输入的关键字,分页搜索ES中spu信息
    @Override
    public JsonPage<SpuForElastic> search(String keyword, Integer page, Integer pageSize) {
        // SpringData分页设置PageRequest.of()第一个参数页面从0开始
        // 所以要page-1
        Page<SpuForElastic> spusPage=spuRepository
                .querySpuSearch(keyword, PageRequest.of(page-1,pageSize));
        // 我们查询出的spusPage返回值,但是不是JsonPage<SpuForElastic>类型,需要转换
        JsonPage<SpuForElastic> jsonPage=new JsonPage<>();
        // 分页信息赋值
        jsonPage.setPage(page);
        jsonPage.setPageSize(pageSize);
        jsonPage.setTotal(spusPage.getTotalElements());
        jsonPage.setTotalPage(spusPage.getTotalPages());
        // 分页数据赋值
        jsonPage.setList(spusPage.getContent());
        // 返回jsonPage对象!!!!
        return jsonPage;
    }


}
